﻿// <copyright file="Weir.cs" company="City of Portland, BES-ASM">
// </copyright>
// <summary>Weir class</summary>

namespace BESASM.EMGAATS.BusinessClasses
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;

  /// <summary>
  /// Weir class
  /// </summary>
  public class Weir : Entity, IWeir
  {
    private string name;
    private INode usNode;
    private INode dsNode;
    private ILink toLink;
    private WeirType weirType;
    private double topElev;
    private double crestElev;
    private double length;
    private double coefficient;
    private bool hasFlapGate;
 
    /// <summary>
    /// Initializes a new instance of the <see cref="Weir" /> class.
    /// </summary>
    /// <param name="id">The ID of the Weir</param>
    public Weir(int id)
      : base(EntityType.Weir, id)
    {
    }

    /// <summary>
    /// Gets or sets the name of the weir
    /// </summary>
    public string WeirName
    {
      get
      {
        return this.name;
      }

      set
      {
        if (value != this.name)
        {
          this.name = value;
          this.NotifyPropertyChanged();
        }
      }
    }

    /// <summary>
    /// Gets or sets the upstream node of the weir
    /// </summary>
    public INode USNode 
    {
      get
      {
        return this.usNode;
      }

      set
      {
        if (value != this.usNode)
        {
          this.usNode = value;
          this.NotifyPropertyChanged();
        }
      }
    }

    /// <summary>
    /// Gets or sets the downstream node of the weir
    /// </summary>
    public INode DSNode
    {
      get
      {
        return this.dsNode;
      }

      set
      {
        if (value != this.dsNode)
        {
          this.dsNode = value;
          this.NotifyPropertyChanged();

          if (value != null)
          {
            this.ToLink = null;
          }
        }
      }
    }

    /// <summary>
    /// Gets or sets the downstream link of the weir
    /// </summary>
    public ILink ToLink
    {
      get
      {
        return this.toLink;
      }

      set
      {
        if (value != this.toLink)
        {
          this.toLink = value;
          this.NotifyPropertyChanged();

          if (value != null)
          {
            this.DSNode = null;
          }
        }
      }
    }

    /// <summary>
    /// Gets or sets the type of weir; <see cref="WeirType"/>
    /// </summary>
    public WeirType WeirType
    {
      get
      {
        return this.weirType;
      }

      set
      {
        if (value != this.weirType)
        {
          this.weirType = value;
          this.NotifyPropertyChanged();
        }
      }
    }

    /// <summary>
    /// Gets or sets the top (crown) elevation of the weir, in feet
    /// </summary>
    public double TopElevFt
    {
      get
      {
        return this.topElev;
      }

      set
      {
        if (value != this.topElev)
        {
          this.topElev = value;
          this.NotifyPropertyChanged();
        }
      }
    }

    /// <summary>
    /// Gets or sets the crest elevation of the weir, in feet
    /// </summary>
    public double CrestElevFt
    {
      get
      {
        return this.crestElev;
      }

      set
      {
        if (value != this.crestElev)
        {
          this.crestElev = value;
          this.NotifyPropertyChanged();
        }
      }
    }

    /// <summary>
    /// Gets or sets the length of the weir, in feet
    /// </summary>
    public double LengthFt
    {
      get
      {
        return this.length;
      }

      set
      {
        if (value != this.length)
        {
          this.length = value;
          this.NotifyPropertyChanged();
        }
      }
    }

    /// <summary>
    /// Gets or sets the coefficient of the weir, in feet
    /// </summary>
    public double Coefficient
    {
      get
      {
        return this.coefficient;
      }

      set
      {
        if (value != this.coefficient)
        {
          this.coefficient = value;
          this.NotifyPropertyChanged();
        }
      }
    }

    /// <summary>
    /// Gets a value indicating whether the weir has a ToLink specified 
    /// </summary>
    public bool HasToLink
    {
      get
      {
        return this.ToLink != null;
      }
    }

    /// <summary>
    /// Gets or sets a value indicating whether the weir has a flap gate
    /// </summary>
    public bool HasFlapGate
    {
      get
      {
        return this.hasFlapGate;
      }

      set
      {
        if (value != this.hasFlapGate)
        {
          this.hasFlapGate = value;
          this.NotifyPropertyChanged();
        }
      }
    }

    /// <summary>
    /// Creates a new entity that is a copy of the current instance.
    /// </summary>
    /// <returns>A new object that is a shallow copy of this instance.</returns>
    public override object Clone()
    {
      // Simple properties and references
      // DO NOT copy Network, clones must be added to a network
      Weir clone = new Weir(this.Id);

      clone.Coefficient = this.Coefficient;
      clone.CrestElevFt = this.CrestElevFt;
      clone.DSNode = this.DSNode;
      clone.HasFlapGate = this.HasFlapGate;
      clone.LengthFt = this.LengthFt;
      clone.TopElevFt = this.TopElevFt;
      clone.ToLink = this.ToLink;
      clone.USNode = this.USNode;
      clone.WeirType = this.WeirType;
      clone.WeirName = this.WeirName;

      this.CloneAuditProperties(clone);

      clone.SetModified(false);
      return clone;
    }

    /// <summary>
    /// Returns a string representation of this weir.
    /// </summary>
    /// <returns>A string representation of this weir.</returns>
    public override string ToString()
    {
      if (this.DSNode != null)
      {
        return string.Format(
          "W{0}/{3} (N{1}-N{2})", 
          this.Id, 
          this.USNode == null ? 0 : this.USNode.Id, 
          this.DSNode.Id,
          this.WeirName);
      }
      else if (this.ToLink != null)
      {
        return string.Format(
          "W{0}/{3} (N{1}-L{2})", 
          this.Id, 
          this.USNode == null ? 0 : this.USNode.Id, 
          this.ToLink.Id,
          this.WeirName);
      }
      else
      {
        return string.Format(
          "W{0}/{2} (N{1}-)", 
          this.Id, 
          this.USNode == null ? 0 : this.USNode.Id,
          this.WeirName);
      }
    }
  }
}
